"""
Base solver types and interfaces
"""

abstract type AbstractSolver end

"""
    Controller

Controls the time integration process with solver, trackers, and storage.
"""
struct Controller{S<:AbstractSolver, T, ST}
    solver::S
    tracker::T
    storage::ST
    kwargs::Dict{Symbol, Any}
    
    function Controller(solver::S; tracker=nothing, storage=nothing, kwargs...) where S
        new{S, typeof(tracker), typeof(storage)}(solver, tracker, storage, Dict(kwargs))
    end
end

function (ctrl::Controller)(pde::AbstractPDE, initial_state, t_span)
    return solve_pde(ctrl.solver, pde, initial_state, t_span, ctrl.tracker, ctrl.storage; ctrl.kwargs...)
end

function registered_solvers()
    return ["ExplicitEulerSolver", "AdaptiveSolver", "RungeKuttaSolver"]
end